package appapi.service.impl;

import appapi.Global.BusinessException;
import appapi.Request.ProjPageReq;
import appapi.Request.bigscreen.AlarmStaticReq;
import appapi.Request.bigscreen.MothCheckStaticReq;
import appapi.Request.bigscreen.SelfEquipUseReq;
import appapi.Request.bigscreen.StaticReq;
import appapi.Vo.bigScreen.EquipTypeTreeVo;
import appapi.Vo.bigScreen.EquipUseStateVo;
import appapi.Vo.bigScreen.OperatorInfoVo;
import appapi.dao.*;
import appapi.dto.bigScreenDto.AreaLevelDto;
import appapi.dto.bigScreenDto.OrgaPathModel;
import appapi.dto.bigScreenDto.ProjOrgaPathModel;
import appapi.entity.Zhongjiao.ProjectDto;
import appapi.entity.bigscreen.AlarmStaticModel;
import appapi.entity.bigscreen.EquipTypeOverageModel;
import appapi.entity.bigscreen.MothCheckStaticModel;
import appapi.entity.bigscreen.SeltEquipUseStaticModel;
import appapi.service.IBigScreenService;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * @author djq
 * @date 2023/5/24 11:51
 * @description:
 */

@Component
public class BigScreenServiceImpl implements IBigScreenService {
    @Resource
    EquipmentMapper equipmentMapper;
    @Resource
    StaffMapper staffMapper;
    @Resource
    EquipStaticMapper equipStaticMapper;
    @Resource
    OrganizationMapper organizationMapper;
    @Resource
    EquipmenttypeMapper equipmenttypeMapper;
    @Resource
    ProjectMapper projectMapper;
    @Resource
    OperatorMapper operatorMapper;
    @Resource
    CertificateMapper certificateMapper;
    @Resource
    AreaMapper areaMapper;

    //region 设备使用情况

    /**
     * 局级
     *
     * @param dto
     * @return
     */
    @Override
    public List<EquipUseStateVo> GetOrgaEquipUseState(AreaLevelDto dto) {
        validate(dto);
        //AreaDto areaDtos = getAreaDtoByName(dto);
        //查到所有公司,根据地区筛选
        List<Map<String, Object>> typeList = organizationMapper.selectOrgListByArea(dto.getAreaId());
        return typeList.stream().map(map -> {
            EquipUseStateVo vo = new EquipUseStateVo();
            Long typeId = (Long) map.get("orgaId");
            String orgaPath = map.get("orgaPathIds").toString();
            String typeName = map.get("orgaName").toString();

            //查到公司下设备数量
            Map<String, Object> equipStateCount = equipmentMapper.getEquipStateCountByOrgaId(orgaPath);

            vo.setEquipNum(Integer.parseInt(equipStateCount.get("equipNum").toString()));
            vo.setUseNum(Integer.parseInt(equipStateCount.get("useNum").toString()));
            vo.setTypeName(typeName);
            vo.setTypeId(typeId);
            vo.setOrgaPathIds(orgaPath);
            return vo;
        }).collect(Collectors.toList());
    }

//    private AreaDto getAreaDtoByName(AreaLevelDto dto) {
//        List<AreaDto> areaDtos = areaMapper.selectByPidAndName(dto.getAreaName());
//        if (areaDtos.size()==0){
//            throw new BusinessException(-1,"该地区不存在");
//        }
//        return areaDtos.get(0);
//    }

    /**
     * 公司级
     *
     * @param dto
     * @return
     */
    public List<EquipUseStateVo> GetCompEquipUseState(AreaLevelDto dto) {
        validate(dto);
        //AreaDto areaDtos = getAreaDtoByName(dto);
        ProjPageReq req = new ProjPageReq();
        req.setAreaPid(dto.getAreaId());
        req.setOrgaPid(dto.getOrgaId());
        //查到所有项目,根据地区,公司筛选
        List<Map<String, Object>> typeList = projectMapper.selectProjList(req);
        return typeList.stream().map(map -> {
            EquipUseStateVo vo = new EquipUseStateVo();
            Long typeId = (Long) map.get("projId");
            String typeName = map.get("projName").toString();
            String orgaPathIds = (String) map.get("orgaPathIds");

            //查到项目下所有设备
            Map<String, Object> equipStateCount = equipmentMapper.getEquipStateCountByProjId(typeId);

            vo.setEquipNum(Integer.parseInt(equipStateCount.get("equipNum").toString()));
            vo.setUseNum(Integer.parseInt(equipStateCount.get("useNum").toString()));
            vo.setTypeName(typeName);
            vo.setTypeId(typeId);
            vo.setOrgaPathIds(orgaPathIds);
            return vo;
        }).collect(Collectors.toList());
    }


    /**
     * 项目级
     *
     * @param dto
     * @return
     */
    public List<EquipUseStateVo> GetProjEquipUseState(AreaLevelDto dto) {
        //List<Long> orgaIds = getUserOrga(dto);
        List<EquipTypeTreeVo> typeList = getEquipTypes();
        return typeList.stream().map(map -> {
            EquipUseStateVo vo = new EquipUseStateVo();
            Long typeId = map.getEquipTypeId();
            String typeName = map.getEquipTypeName();

            //查到项目下该类型的设备数
            Map<String, Object> equipStateCount = equipmentMapper.getEquipStateCountByProjAndType(typeId, dto.getProjId());

            vo.setEquipNum(Integer.parseInt(equipStateCount.get("equipNum").toString()));
            vo.setUseNum(Integer.parseInt(equipStateCount.get("useNum").toString()));
            vo.setTypeName(typeName);
            vo.setTypeId(typeId);
            return vo;
        }).collect(Collectors.toList());
    }
    //endregion

    //region 人员信息

    /**
     * 局级
     *
     * @param dto
     * @return
     */
    @Override
    public List<OperatorInfoVo> getOrgaOperatorInfo(AreaLevelDto dto) {
        validate(dto);
        //AreaDto areaDtos = getAreaDtoByName(dto);
        //查到所有公司,根据地区筛选
        List<Map<String, Object>> typeList = organizationMapper.selectOrgListByArea(dto.getAreaId());
        return typeList.stream().map(map -> {
            OperatorInfoVo vo = new OperatorInfoVo();
            Long typeId = (Long) map.get("orgaId");
            String orgaPath = map.get("orgaPathIds").toString();
            String typeName = map.get("orgaName").toString();

            //查到公司下人员数量
            List<Map<String, Object>> equipStateCount = operatorMapper.getOperatorInfoByOrgaId(orgaPath);
            List<Long> operId = equipStateCount.stream().map(item -> (Long) item.get("operId")).collect(Collectors.toList());
            //查到人员证书过期数量
            Integer eNum;
            if (operId.size() > 0){
                eNum = certificateMapper.selectExpirNumByOperId(operId)==null?0:certificateMapper.selectExpirNumByOperId(operId);
            }else {
                eNum = 0;
            }


            vo.setOperaNum(equipStateCount.size());
            vo.setCetifiExpirNum(eNum);
            vo.setTypeName(typeName);
            vo.setTypeId(typeId);
            vo.setOrgaPathIds(orgaPath);
            return vo;
        }).collect(Collectors.toList());
    }

    /**
     * 公司级
     *
     * @param dto
     * @return
     */
    @Override
    public List<OperatorInfoVo> getCompOperatorInfo(AreaLevelDto dto) {
        validate(dto);
        //AreaDto areaDtos = getAreaDtoByName(dto);
        ProjPageReq req = new ProjPageReq();
        req.setAreaPid(dto.getAreaId());
        req.setOrgaPid(dto.getOrgaId());
        //查到所有项目,根据地区,公司筛选
        List<Map<String, Object>> typeList = projectMapper.selectProjList(req);
        return typeList.stream().map(map -> {
            OperatorInfoVo vo = new OperatorInfoVo();
            Long typeId = (Long) map.get("projId");
            String typeName = map.get("projName").toString();
            String orgaPathIds = (String) map.get("orgaPathIds");

            //查到项目下所有人员
            List<Map<String, Object>> equipStateCount = operatorMapper.getOperatorInfoByProjId(typeId);
            List<Long> operId = equipStateCount.stream().map(item -> (Long) item.get("operId")).collect(Collectors.toList());
            //查到人员证书过期数量
            Integer eNum = operId.size() > 0 ? certificateMapper.selectExpirNumByOperId(operId) : 0;

            vo.setOperaNum(equipStateCount.size());
            vo.setCetifiExpirNum(eNum);
            vo.setTypeName(typeName);
            vo.setTypeId(typeId);
            vo.setOrgaPathIds(orgaPathIds);
            return vo;
        }).collect(Collectors.toList());
    }

    /**
     * 项目级
     *
     * @param dto
     * @return
     */
    @Override
    public List<OperatorInfoVo> getProjOperatorInfo(AreaLevelDto dto) {
        validate(dto);

        List<EquipTypeTreeVo> typeList = getEquipTypes();
        return typeList.stream().map(map -> {
            OperatorInfoVo vo = new OperatorInfoVo();
            Long typeId = map.getEquipTypeId();
            String typeName = map.getEquipTypeName();

            //查到设备下人员数
            List<Map<String, Object>> equipStateCount = operatorMapper.getOperatorInfoByTypeId(typeId, dto.getProjId());
            List<Long> operId = equipStateCount.stream().map(item -> (Long) item.get("operId")).collect(Collectors.toList());
            //查到人员证书过期数量
            Integer eNum = operId.size() > 0 ? certificateMapper.selectExpirNumByOperId(operId) : 0;

            vo.setOperaNum(equipStateCount.size());
            vo.setCetifiExpirNum(eNum);
            vo.setTypeName(typeName);
            vo.setTypeId(typeId);
            return vo;
        }).collect(Collectors.toList());
    }

    //endregion

    //region 设备总数情况

    /**
     * 局级
     *
     * @param dto
     * @return
     */
    @Override
    public List<EquipUseStateVo> GetOrgaEquipNum(AreaLevelDto dto) {
        validate(dto);
        //查到所有类型
        List<EquipTypeTreeVo> equipTypes = getSpecilType();

        //List<Map<String, Object>> typeList = organizationMapper.selectOrgListByArea(dto.getAreaId());
        //查到所有公司下的项目,根据地区筛选
        List<Map<String, Object>> typeList = organizationMapper.selectOrgProjListByArea(dto.getAreaId());

        List<Long> orgaIds = typeList.stream().map(orgas -> (Long) orgas.get("projOrgaId")).collect(Collectors.toList());
        //循环所有类型并赋值
        return equipTypes.stream().map(map -> {
            EquipUseStateVo vo = new EquipUseStateVo();
            Long typeId = map.getEquipTypeId();
            String typeName = map.getEquipTypeName();
            String screen = map.getEquipTypeScreen();

            //查到该类型下,公司所拥有的设备数量
            Map<String, Object> equipNumByOrga = equipmentMapper.getEquipNumByOrga(orgaIds, null,screen);

            vo.setEquipNum(Integer.parseInt(equipNumByOrga.get("equipNum").toString()));
            vo.setTypeName(screen);
            vo.setTypeId(typeId);
            return vo;
        }).collect(Collectors.toList());
    }

    /**
     * 公司级
     *
     * @param dto
     * @return
     */
    public List<EquipUseStateVo> GetProjEquipNum(AreaLevelDto dto) {
        validate(dto);
        if (ObjectUtils.isEmpty(dto.getOrgaId())) {
            throw new BusinessException(500, "公司不能为空!");
        }
        //查到所有类型
        List<EquipTypeTreeVo> equipTypes = getSpecilType();
        ProjPageReq req = new ProjPageReq();
        req.setAreaPid(dto.getAreaId());
        req.setOrgaPid(dto.getOrgaId());
        //查到所有项目,根据地区,公司筛选
        List<Map<String, Object>> typeList = projectMapper.selectProjList(req);
        List<Long> projIds = typeList.stream().map(projId -> (Long) projId.get("projId")).collect(Collectors.toList());
        return equipTypes.stream().map(map -> {
            EquipUseStateVo vo = new EquipUseStateVo();
            Long typeId = map.getEquipTypeId();
            String typeName = map.getEquipTypeName();
            String screen = map.getEquipTypeScreen();

            //查到该类型下,项目所拥有的设备数量
            Map<String, Object> equipNumByOrga = equipmentMapper.getEquipNumByOrga(null, projIds, screen);

            vo.setEquipNum(Integer.parseInt(equipNumByOrga.get("equipNum").toString()));
            vo.setTypeName(screen);
            vo.setTypeId(typeId);
            return vo;
        }).collect(Collectors.toList());
    }


    /**
     * 项目级
     *
     * @param dto
     * @return
     */
    public List<EquipUseStateVo> GetCompEquipNum(AreaLevelDto dto) {
        //List<Long> orgaIds = getUserOrga(dto);
        if (ObjectUtils.isEmpty(dto.getOrgaId())) {
            throw new BusinessException(500, "组织机构不能为空!");
        }
        List<ProjectDto> projectDtos = projectMapper.selectByProjectByOrgaId(dto.getOrgaId());

        if (projectDtos.size()==0){
            return new ArrayList<>();
        }

        List<EquipTypeTreeVo> typeList = getEquipTypes();
        return typeList.stream().map(map -> {
            EquipUseStateVo vo = new EquipUseStateVo();
            Long typeId = map.getEquipTypeId();
            String typeName = map.getEquipTypeName();

            //查到项目下该类型的设备数
            Map<String, Object> equipStateCount = equipmentMapper.getEquipStateCountByProjAndType(typeId,projectDtos.get(0).getProjId());

            vo.setEquipNum(Integer.parseInt(equipStateCount.get("equipNum").toString()));
            vo.setUseNum(Integer.parseInt(equipStateCount.get("useNum").toString()));
            vo.setTypeName(typeName);
            vo.setTypeId(typeId);
            return vo;
        }).collect(Collectors.toList());
    }

    private  List<EquipTypeTreeVo> getEquipTypes() {
        List<EquipTypeTreeVo> typeList = equipmenttypeMapper.selectAll(null,"特种设备");
        return typeList;
    }

    private  List<EquipTypeTreeVo> getSpecilType() {
        List<EquipTypeTreeVo> typeList = equipmenttypeMapper.selectSpecil();
        return typeList;
    }
    //endregion


    private static void validate(AreaLevelDto dto) {
        if (dto.getAreaId() == null && dto.getOrgaId() == null && dto.getProjId() == null) {
            throw new BusinessException(500, "参数不能为空!");
        }
    }

    //(根据人员权限查看数据)弃用
    private List<Long> getUserOrga(AreaLevelDto dto) {
//        String[] userInfo = JwtUtil.getUserInfoByJwtToken(request);
//        Map<String, Object> user = staffMapper.selectMobile(userInfo[1]);
//        if (user == null) {
//            throw new BusinessException(500, "人员不存在");
//        }
//        //拿到该人员的组织结构路径id
//        String orgaPathIds = user.get("orgaId").toString();


        //如果是按照选择查看数据的话,则跳过上面步骤
//        OrganizaPageReq req = new OrganizaPageReq();
//        req.setOrgaPathIds(orgaPathIds);
//        //查到该路径子级所有的组织机构的id
//        List<Long> orgaIds = organizationMapper.selectOrgListByPath(req).stream().map(GetOrgListVo::getOrgaId).collect(Collectors.toList());
//        return orgaIds;
        return null;
    }


    @Override
    public List<SeltEquipUseStaticModel> GetOrgaSelfEquipUseStatic(SelfEquipUseReq req) {
        //查到所有公司,根据地区筛选
        List<OrgaPathModel> orgaList = organizationMapper.selectOrgListByAreaModel(req.getAreaId(), req.getOrgaId());
        List<SeltEquipUseStaticModel> modelList = new ArrayList<>();
        for (OrgaPathModel orga : orgaList
        ) {
            SeltEquipUseStaticModel model = equipStaticMapper.selectSelfEquipUseStatic(orga.getOrgaPathIds());
            model.setSelfEquip(orga.getCompName());
            model.setOrgaPathIds(orga.getOrgaPathIds());
            BigDecimal userRate = new BigDecimal("0.00");
            if (model.getSelfTotal() != 0) {
                userRate = new BigDecimal((model.getSelfTotal() - model.getSelfUnUsed()) / model.getSelfTotal());
            }
            DecimalFormat df2 = new DecimalFormat("#0.00%");
            model.setUsageRate(df2.format(userRate));
            modelList.add(model);
        }
        return modelList;
    }

    /**
     * 获取自有设备使用统计（公司级）
     *
     * @param req
     * @return
     */
    @Override
    public List<SeltEquipUseStaticModel> GetCompSelfEquipUseStatic(SelfEquipUseReq req) {
        //查到所有公司,根据地区筛选
        List<ProjOrgaPathModel> orgaList = organizationMapper.selectProjListByAreaModel(req.getAreaId(), req.getOrgaId());
        List<SeltEquipUseStaticModel> modelList = new ArrayList<>();
        for (ProjOrgaPathModel orga : orgaList
        ) {
            SeltEquipUseStaticModel model = equipStaticMapper.selectSelfEquipUseStatic(orga.getOrgaPathIds());
            model.setSelfEquip(orga.getProjName());
            model.setOrgaPathIds(orga.getOrgaPathIds());
            BigDecimal userRate = new BigDecimal("0.00");
            if (model.getSelfTotal() != 0) {
                userRate = new BigDecimal((model.getSelfTotal() - model.getSelfUnUsed()) / model.getSelfTotal());
            }
            DecimalFormat df2 = new DecimalFormat("#0.00%");
            model.setUsageRate(df2.format(userRate));
            modelList.add(model);
        }
        return modelList;
    }

    @Override
    public List<SeltEquipUseStaticModel> GetProjSelfEquipUseStatic(Long orgaId) {
        //获取项目设备类型
        List<SeltEquipUseStaticModel> modelList = equipStaticMapper.selectProjSelfEquipUseStatic(orgaId);
        for (SeltEquipUseStaticModel model : modelList
        ) {
            BigDecimal userRate = new BigDecimal("0.00");
            if (model.getSelfTotal() != 0) {
                userRate = new BigDecimal((model.getSelfTotal() - model.getSelfUnUsed()) / model.getSelfTotal());
            }
            DecimalFormat df2 = new DecimalFormat("#0.00%");
            model.setUsageRate(df2.format(userRate));
        }
        return modelList;
    }

    /**
     * 月检--局级
     *
     * @param req
     * @return
     */
    @Override
    public List<MothCheckStaticModel> GetOrgaMothCheckStatic(MothCheckStaticReq req) {
        //查到所有公司,根据地区筛选
        List<OrgaPathModel> orgaList = organizationMapper.selectOrgListByAreaModel(req.getAreaId(), req.getOrgaId());
        List<MothCheckStaticModel> modelList = new ArrayList<>();
        for (OrgaPathModel orga : orgaList
        ) {
            MothCheckStaticModel model = equipStaticMapper.selectMothCheckStatic(orga.getOrgaPathIds());
            model.setEquipType(orga.getCompName());
            model.setOrgaPathIds(orga.getOrgaPathIds());
            BigDecimal userRate = new BigDecimal("0.00");
            if (model.getCheckTotal() != 0) {
                userRate = new BigDecimal(model.getHasCheck() / model.getCheckTotal());
            }
            DecimalFormat df2 = new DecimalFormat("#0.00%");
            model.setCompletionRate(df2.format(userRate));
            modelList.add(model);
        }
        return modelList;
    }

    /**
     * 月检--公司级
     *
     * @param req
     * @return
     */
    @Override
    public List<MothCheckStaticModel> GetCompMothCheckStatic(MothCheckStaticReq req) {
        //查询公司项目信息,根据地区筛选
        List<ProjOrgaPathModel> orgaList = organizationMapper.selectProjListByAreaModel(req.getAreaId(), req.getOrgaId());
        List<MothCheckStaticModel> modelList = new ArrayList<>();
        for (ProjOrgaPathModel orga : orgaList
        ) {
            MothCheckStaticModel model = equipStaticMapper.selectMothCheckStatic(orga.getOrgaPathIds());
            model.setEquipType(orga.getProjName());
            model.setOrgaPathIds(orga.getOrgaPathIds());
            BigDecimal userRate = new BigDecimal("0.00");
            if (model.getCheckTotal() != 0) {
                userRate = new BigDecimal(model.getHasCheck() / model.getCheckTotal());
            }
            DecimalFormat df2 = new DecimalFormat("#0.00%");
            model.setCompletionRate(df2.format(userRate));
            modelList.add(model);
        }
        return modelList;
    }

    @Override
    public List<MothCheckStaticModel> GetProjMothCheckStatic(Long orgaId) {
        //获取项目设备类型
        List<MothCheckStaticModel> modelList = equipStaticMapper.selectProjMothCheckStatic(orgaId);
        for (MothCheckStaticModel model : modelList
        ) {
            BigDecimal userRate = new BigDecimal("0.00");
            if (model.getCheckTotal() != 0) {
                userRate = new BigDecimal(model.getHasCheck() / model.getCheckTotal());
            }
            DecimalFormat df2 = new DecimalFormat("#0.00%");
            model.setCompletionRate(df2.format(userRate));
        }
        return modelList;
    }

    @Override
    public List<EquipTypeOverageModel> GetOrgaEquipOverageStatic(StaticReq req) {
         //查到所有公司,根据地区筛选
        List<OrgaPathModel> orgaList = organizationMapper.selectOrgListByAreaModel(req.getAreaId(), req.getOrgaId());
        List<EquipTypeOverageModel> modelList = new ArrayList<>();
        for (OrgaPathModel orga : orgaList
        ) {
            EquipTypeOverageModel model = equipStaticMapper.selectEquipOverageStatic(orga.getOrgaPathIds());
            model.setEquipType(orga.getCompName());
            model.setOrgaPathIds(orga.getOrgaPathIds());
            modelList.add(model);
        }
        return modelList;
    }
    @Override
    public List<EquipTypeOverageModel> GetCompEquipOverageStatic(StaticReq req) {
        //查到所有公司,根据地区筛选
        List<ProjOrgaPathModel> orgaList = organizationMapper.selectProjListByAreaModel(req.getAreaId(), req.getOrgaId());
        List<EquipTypeOverageModel> modelList = new ArrayList<>();
        for (ProjOrgaPathModel orga : orgaList
        ) {
            EquipTypeOverageModel model = equipStaticMapper.selectEquipOverageStatic(orga.getOrgaPathIds());
            model.setEquipType(orga.getProjName());
            modelList.add(model);
        }
        return modelList;
    }
    @Override
    public List<EquipTypeOverageModel> GetProjEquipOverageStatic(Long orgaId) {
        //根据类型统计设备超限数量
        List<EquipTypeOverageModel> modelList = equipStaticMapper.selectProjEquipOverageStatic(orgaId);
        return modelList;
    }

    @Override
    public List<AlarmStaticModel> GetAlarmStatic(AlarmStaticReq req) {
        return equipStaticMapper.selectAlarmStatic(req);
    }
}
